home *** CD-ROM | disk | FTP | other *** search
/ Joystick Magazine 1996 May / cd joy 71No13.iso / pc / demos / eurosoc / source / ball.cpp < prev    next >
C/C++ Source or Header  |  1996-03-07  |  37KB  |  1,614 lines

  1. /******************************************************************************
  2. *******************************************************************************
  3.  
  4. Ball movement routines...
  5.  
  6. ******************************************************************************
  7. *****************************************************************************/
  8.  
  9. #include "global.h"
  10.  
  11. #include "defines.h"
  12. #include "externs.h"
  13. #include "audio.h"
  14. #include "front.h"
  15. #include "data.h"
  16. #include "eurofrnt\euro_int.h"
  17.  
  18. extern match_data match_info;
  19.  
  20. extern setup_info setup;
  21. extern stad_info stadlist[];
  22.  
  23. /******************************************************************************
  24. *****************************************************************************/
  25.  
  26. /******************************************************************************
  27. *****************************************************************************/
  28.  
  29. float get_angle(float x,float y,float d)
  30. {
  31.     float a=(acos(x/d))*180/PI;
  32.     if (y<0)
  33.         a=360-a;
  34.     return(a);
  35. }
  36.  
  37. /******************************************************************************
  38. *****************************************************************************/
  39.  
  40. void get_xydis_from_ang(float a,float d)
  41. {
  42.     ballxdis=((float)(d)*cos(a*PI/180));
  43.     ballydis=-((float)(d)*sin(a*PI/180));
  44. }
  45.     
  46. /******************************************************************************
  47. *****************************************************************************/
  48.  
  49. float get_s_angle(float z,float d)
  50. {
  51.     float a=(asin(z/d))*180/PI;
  52.     return(a);
  53. }
  54.  
  55. /******************************************************************************
  56. *****************************************************************************/
  57.  
  58. void get_zdis_from_ang(float a,float d)
  59. {
  60.     ballzdis=((float)(d)*sin(a*PI/180));
  61. }
  62.  
  63. /******************************************************************************
  64. *****************************************************************************/
  65.  
  66. void stop_ball_spin()
  67. {
  68.     swerve=0;full_zspin=0;full_xyspin=0;
  69.     ball_zspin=0;ball_xyspin=0;
  70.     max_sw_factor=0;
  71.     swerve_factor=0;
  72.     rebound_ball=FALSE;
  73.     headed_ball=FALSE;
  74. }
  75.  
  76. /******************************************************************************
  77. *****************************************************************************/
  78.  
  79. void swerve_xyz()
  80. {
  81.     float x,y,z,d,dz,dn;
  82.     d=calc_dist(ballxdis,ballydis);
  83.     x=ballxdis/d;
  84.     y=ballydis/d;
  85.     dz=calc_dist(ballzdis,d);
  86.     z=ballzdis/dz;
  87.     dn=d/dz;
  88.  
  89.     ballxdis=d*((x*cos(ball_xyspin))-(y*sin(ball_xyspin)));
  90.     ballydis=d*((y*cos(ball_xyspin))+(x*sin(ball_xyspin)));
  91.     ballzdis=d*((z*cos(ball_zspin))+(dn*sin(ball_zspin)));
  92. }
  93.  
  94. /******************************************************************************
  95. *****************************************************************************/
  96.  
  97. void inc_swerve()
  98. {
  99.     spin_cnt++;
  100.       ball_zspin=-(full_zspin*(SW_HOLD_FACTOR/(SW_HOLD_FACTOR+spin_cnt)));
  101.  
  102.     if (swerve<0)
  103.         ball_xyspin=-(full_xyspin*(SW_HOLD_FACTOR/(SW_HOLD_FACTOR+spin_cnt)));
  104.     else
  105.         ball_xyspin=(full_xyspin*(SW_HOLD_FACTOR/(SW_HOLD_FACTOR+spin_cnt)));
  106. }
  107.  
  108. /******************************************************************************
  109. *****************************************************************************/
  110.  
  111. void get_aftert_spin()
  112. {
  113.     spin_cnt++;
  114.     float xys,zs;
  115.     float x,y,z,d,dz,dn;
  116.     d=calc_dist(ballxdis,ballydis);
  117.     x=ballxdis/d;
  118.     y=ballydis/d;
  119.     dz=calc_dist(ballzdis,d);
  120.     z=ballzdis/dz;
  121.     dn=d/dz;
  122.     
  123.     char u=after_touch_on-1;
  124.  
  125. #ifdef SUPPORT_LP
  126.     if (users[u].control==LOGPAD_CTRL)
  127.     {
  128.         if (!prediction)
  129.             xys=1;
  130.  
  131.         xys=0;
  132.         if (users_dir[u].f&4 && !(users_dir[u].f&8))
  133.             xys=1;
  134.  
  135.         if (users_dir[u].f&8 && !(users_dir[u].f&4))
  136.             xys=-1;
  137.     }
  138.     else
  139.     {
  140.         xys=((users_dir[u].x*shoot_y)-(users_dir[u].y*shoot_x));
  141.     }
  142. #else
  143.         xys=((users_dir[u].x*shoot_y)-(users_dir[u].y*shoot_x));
  144. #endif
  145.  
  146.     zs=((users_dir[u].x*shoot_x)+(users_dir[u].y*shoot_y));
  147.  
  148.     ball_xyspin=-(xys*full_xyspin*(SW_HOLD_FACTOR/(SW_HOLD_FACTOR+spin_cnt)));
  149.     ball_zspin=-(zs*full_zspin*(SW_HOLD_FACTOR/(SW_HOLD_FACTOR+spin_cnt)));
  150. //    ball_zspin=0.05;
  151.     ballxdis=d*((x*cos(ball_xyspin))-(y*sin(ball_xyspin)));
  152.     ballydis=d*((y*cos(ball_xyspin))+(x*sin(ball_xyspin)));
  153.     ballzdis=dz*((z*cos(ball_zspin))+(dn*sin(ball_zspin)));
  154.     
  155.     zs=0;
  156. }
  157.  
  158. /******************************************************************************
  159. *****************************************************************************/
  160.  
  161. void add_spin_fx()
  162. {
  163. //    if (!prediction)
  164.     {
  165.         if (swerve!=0)
  166.         {
  167.             float d=calc_dist(ballxdis,ballydis);
  168.             if (d<1)
  169. // Ball is hardly travelling (swerve OFF)
  170.  
  171.                 stop_ball_spin();
  172.             else
  173.             {
  174.                 inc_swerve();
  175.                 swerve_xyz();
  176.             }
  177.         }
  178.         else
  179.         {
  180.             if (after_touch_on)
  181.                 get_aftert_spin();
  182.         }
  183.  
  184.         if (shot_pending)
  185.         {
  186.             swerve_factor=ABS(ball_xyspin);
  187.             if (swerve_factor>max_sw_factor)
  188.                 max_sw_factor=swerve_factor;
  189.         }
  190.     }
  191. }
  192.  
  193. /******************************************************************************
  194. *****************************************************************************/
  195.  
  196. void move_ball()
  197. {
  198.     ballx+=ballxdis;
  199.     bally+=ballydis;
  200.  
  201.     if (prediction)
  202.     {
  203.         ns_ballx=ballx;
  204.         ns_bally=bally;
  205.         ns_ballz=ballz;
  206.     }
  207.  
  208.     if (ball_inair)
  209.     {
  210.  
  211.         ballz+=ballzdis;
  212.         
  213.         if (ballz<ball_diam/2)
  214.         {
  215.             ballz=ball_diam/2;
  216.             ballzdis=-ballzdis;
  217.             ballzdis-=bounce_dis;
  218. // Landing friction...
  219.             ballxdis=ballxdis-(0.1*ballxdis);
  220.             ballydis=ballydis-(0.1*ballydis);
  221.  
  222.             if (ballzdis<0)
  223.             {
  224.                 ballzdis=0;
  225.                 ball_inair=0;
  226.             }
  227.             else
  228.                 if (!prediction)
  229.                 {
  230.                     if (ABS(ballzdis)>7)
  231.                         play_fx(PS_HARDBOUNCE,ballx,bally);
  232.                     else
  233.                         play_fx(PS_SOFTBOUNCE,ballx,bally);
  234.                 }
  235.         }
  236.  
  237.         if (ball_inair)
  238.         {
  239.             add_spin_fx();
  240.             if (!prediction)
  241.             {
  242.                 ball_horz_ang+=ball_xyspin*40;
  243.  
  244.                 float x,y,d;
  245.                 d=((cos(ball_horz_ang)*launch_x)+(sin(ball_horz_ang)*launch_y));
  246.  
  247.                 if (d>1.0)
  248.                     d=1;
  249.  
  250.                 if (d<-1.0)
  251.                     d=-1;
  252.  
  253.                 ball_vert_ang+=d*(-ball_zspin*40);
  254.  
  255.                 ball_vert_ang+=IN_AIR_SPIN*launch_type;
  256.             }
  257.         }
  258.     }
  259. }
  260.  
  261. /******************************************************************************
  262. *****************************************************************************/
  263.  
  264. void grav_ball()
  265. {
  266.     if (ball_inair)
  267.     {
  268.         ballzdis-=gravity;
  269.     }
  270. }
  271.  
  272. /******************************************************************************
  273. *****************************************************************************/
  274.  
  275. void ball_friction()
  276. {
  277.     float    friction_factor;
  278.  
  279.     if (ball_inair)
  280.         friction_factor=AIR_FRICTION;
  281.     else
  282.         friction_factor=GRND_FRICTION;
  283.         
  284.     if (wind_on)
  285. // Wind Fx...
  286.     {
  287.         float wf=wind_speed/(800-(ballz*2));
  288.         if (wf>MAX_WIND)
  289.             wf=MAX_WIND;
  290.  
  291.         ballxdis+=wind_x*wf;
  292.         ballydis+=wind_y*wf;
  293.     }
  294.  
  295.     ballxdis=(friction_factor*ballxdis);
  296.     ballydis=(friction_factor*ballydis);
  297.  
  298.     if (!ball_inair)
  299.     {
  300.         if ((ballxdis>-0.25) && (ballxdis<0.25))
  301.             ballxdis=0;
  302.         
  303.         if ((ballydis>-0.25) && (ballydis<0.25))
  304.             ballydis=0;
  305.     }
  306. }
  307.  
  308. /******************************************************************************
  309. *****************************************************************************/
  310.  
  311. void roll_ball()
  312. {
  313.     if ((!prediction) && (!ball_inair))
  314.     {
  315. // Roll ball...
  316.         float x=ballxdis;
  317.         float y=ballydis;
  318.         float d=calc_dist(x,y);
  319.         x=x/d;
  320.         y=y/d;
  321.  
  322.         ball_horz_ang=acos(x);
  323.         if (y<0)
  324.             ball_horz_ang=(PI*2)-ball_horz_ang;
  325.  
  326.         ball_vert_ang+=d/ball_diam;
  327.     }
  328. }
  329.  
  330. /******************************************************************************
  331. *****************************************************************************/
  332.  
  333. void ball_trajectory()
  334. {
  335.     if (!ball_poss)
  336.     {
  337.         if (game_action==-1)
  338.             game_action=0;
  339.         move_ball();
  340.         grav_ball();
  341.         ball_friction();
  342.     }
  343.  
  344.     if (ballxdis || ballydis)
  345.     {
  346.         ball_still=0;
  347.         if ((!ball_in_hands) || (!ball_poss))
  348.             roll_ball();
  349.     }
  350.     else
  351.         ball_still=1;
  352. }
  353.  
  354. /******************************************************************************
  355. *****************************************************************************/
  356.  
  357. void get_ball_zone()
  358. {
  359.     if ((!ball_out_of_play) && ((!match_mode) || (match_mode>GOAL_KICK_BR)))
  360.     {
  361.         if (ball_in_hands)
  362.         {
  363.             if (ball_poss==KP_A)
  364.             {
  365. // Pretend Goal kick for A...
  366.                 ball_zone1=11;
  367.                 ball_zone2=20;
  368.             }
  369.             else
  370.             {
  371.                 if (ball_poss==KP_B)
  372.                 {
  373. // Pretend Goal kick for B...
  374.                     ball_zone1=19;
  375.                     ball_zone2=12;
  376.                 }
  377.             }
  378.         }
  379.         else
  380.         {
  381.             int bx1=ballx;
  382.             int bx2=ballx;
  383.             int by1=bally;
  384.             int by2=bally;
  385.             bx1=((bx1+(zone_wid/2))/(zone_wid));
  386.             zone1_x=bx1*zone_wid;
  387.             bx2=7-bx1;
  388.             zone2_x=bx2*zone_wid;
  389.             by1=((by1+(zone_hgt/2))/(zone_hgt));
  390.             zone1_y=by1*zone_hgt;
  391.             by2=3-by1;
  392.             zone2_y=by2*zone_hgt;
  393.             if (by2>=0)
  394.             {
  395.                 ball_zone1=(by1*8)+bx1;
  396.                 ball_zone2=(by2*8)+bx2;
  397.             }
  398.         }
  399.     }
  400. }
  401.  
  402. /******************************************************************************
  403. *****************************************************************************/
  404.  
  405. void launch_ball(int p)
  406. {
  407.     float d=calc_dist(ballxdis,ballydis);
  408.     if (d>0.2)
  409.     {
  410.         launch_x=ballxdis/d;
  411.         launch_y=ballydis/d;
  412.         ball_horz_ang=acos(launch_x);
  413.         if (launch_y<0)
  414.             ball_horz_ang=(PI*2)-ball_horz_ang;
  415.           launch_type=p;
  416.     }
  417. }
  418.  
  419. /******************************************************************************
  420. *****************************************************************************/
  421.  
  422. void reset_shot()
  423. {
  424.     real_shot=FALSE;
  425.     shot_acknowledged=FALSE;
  426.     shot_pending=FALSE;
  427.     after_touch_on=FALSE;
  428.     swerve=FALSE;
  429. }
  430.  
  431. /******************************************************************************
  432. *****************************************************************************/
  433.  
  434. void new_shot(int p)
  435. {
  436.     if (men_in_wall>1)
  437.         wall_is_up=TRUE;
  438.     else
  439.         wall_is_up=FALSE;
  440.  
  441.     float r;
  442.     shot_acknowledged=FALSE;
  443.     must_shoot=FALSE;
  444.     shooter=p;
  445.     if (ballx>cntspot_x || (ballx<=cntspot_x && ballxdis>ABS(ballydis)))
  446. // Keeper B to see it...
  447.     {
  448.         r=teams[KP_B-1].tm_dist;
  449.         shot_pending=-1-((128-teams[KP_B-1].tm_vis)/10);
  450.  
  451.         if (r<LONG_RANGE && shot_pending<-1)
  452.             shot_pending=(((r*1.4)/LONG_RANGE)*(shot_pending+1))-1;
  453.  
  454.         if (penalty_shot && teams[KP_B-1].control)
  455.             shot_pending=-1;
  456.     }
  457.     else
  458. // Keeper A to see it...
  459.         if (ballx<=cntspot_x || (ballx>cntspot_x && ballxdis<ABS(ballydis)))
  460.         {
  461.             r=teams[KP_A-1].tm_dist;
  462.             shot_pending=-1-((128-teams[KP_A-1].tm_vis)/10);
  463.  
  464.             if (r<LONG_RANGE && shot_pending<-1)
  465.                 shot_pending=(((r*1.4)/LONG_RANGE)*(shot_pending+1))-1;
  466.  
  467.             if (penalty_shot && teams[KP_A-1].control)
  468.                 shot_pending=-1;
  469.         }
  470. }
  471.  
  472. /******************************************************************************
  473. *****************************************************************************/
  474.  
  475. void reset_ball()
  476. {
  477.     holder_lose_ball();
  478.     ballz=ball_diam/2;ballxdis=0;ballydis=0;ballzdis=0;
  479.     ball_zspin=0;ball_xyspin=0;
  480.     ball_inair=0;ball_still=1;super_shot=0;
  481.     ball_in_goal=FALSE;
  482.     last_touch=0;
  483.     shot_attempt=0;
  484.     stop_ball_spin();
  485.     reset_all_ideas();
  486.     reset_shot();
  487.     use_ball_limit=FALSE;
  488. }
  489.  
  490. /******************************************************************************
  491. *****************************************************************************/
  492.  
  493. void respot_ball()
  494. {
  495.     if (shot_pending && match_mode>=GOAL_KICK_TL && match_mode<=GOAL_KICK_BR)
  496.         fired_a_shot=TRUE;
  497.     else
  498.         fired_a_shot=FALSE;
  499.  
  500.     reset_ball();
  501.  
  502.     if (!penalty_game)
  503.     {
  504.         if (last_goal==1)    
  505.         {
  506.             match_mode=CENTRE_B;
  507.             last_goal=0;
  508.         }
  509.     
  510.         if (last_goal==2)
  511.         {
  512.             match_mode=CENTRE_A;
  513.             last_goal=0;
  514.         }
  515.     
  516.         if (match_mode)
  517.             init_match_mode();        
  518.     }
  519. }
  520.  
  521. /******************************************************************************
  522. *****************************************************************************/
  523.  
  524. void shot_passed()
  525. {
  526.     float d;
  527.     if (ballx<0)
  528.     {
  529. // Left goal...
  530.         d=calc_dist(ballx,bally-cntspot_y);
  531.         if (d>prat*8)
  532.             shot_missed=-25;        // Laughable attempt!
  533.         else
  534.             if (ballz>prat*5)
  535.                 shot_missed=-25;        // Laughable attempt!
  536.             else
  537.                 shot_missed=25;        // good attempt!
  538.     }
  539.     else
  540.     {
  541.         if (ballx>pitch_len)
  542.         {
  543. // Right goal...
  544.             d=calc_dist(ballx-pitch_len,bally-cntspot_y);
  545.             if (d>prat*8)
  546.                 shot_missed=-15;        // Laughable attempt!
  547.             else
  548.                 if (ballz>prat*5)
  549.                     shot_missed=-15;        // Laughable attempt!
  550.                 else
  551.                     shot_missed=15;        // good attempt!
  552.         }
  553.     }
  554. }
  555.  
  556. /******************************************************************************
  557. *****************************************************************************/
  558.  
  559. void stadium_bounds()
  560. {
  561.     if (ballx>(pitch_len+stadlist[setup.stadium].st_l))
  562.     {
  563.         ballx=(pitch_len+stadlist[setup.stadium].st_l);
  564.         ballxdis=-ballxdis;
  565.     }
  566.     else
  567.         if (ballx<-stadlist[setup.stadium].st_l)
  568.         {
  569.             ballx=-stadlist[setup.stadium].st_l;
  570.             ballxdis=-ballxdis;
  571.         }
  572.         else
  573.             if (bally>(pitch_wid+stadlist[setup.stadium].st_w))
  574.             {
  575.                 bally=(pitch_wid+stadlist[setup.stadium].st_w);
  576.                 ballydis=-ballydis;
  577.             }
  578.             else
  579.                 if (bally<-stadlist[setup.stadium].st_w)
  580.                 {
  581.                     bally=-stadlist[setup.stadium].st_w;
  582.                     ballydis=-ballydis;
  583.                 }
  584. }
  585.  
  586. /******************************************************************************
  587. *****************************************************************************/
  588.  
  589. void pitch_bounds()
  590. {
  591.     if ((ballx<0) || (ballx>=pitch_len) || (bally<0) || (bally>=pitch_wid))
  592.     {
  593.         if ((!((ball_poss) && (teams[ball_poss-1].tm_act==THROW_ACT)))
  594.             && (just_thrown==FALSE))
  595.         {
  596. // Not taking throw in...
  597.             if (play_advantage)
  598.             {
  599.                 retake_foul();
  600.             }
  601.             else
  602.             {
  603.                 use_ball_limit=TRUE;
  604.                 ballx_out=ballx;
  605.                 bally_out=bally;
  606.                 ballz_out=ballz;
  607.  
  608.                 if (shot_pending)
  609.                     shot_passed();            // For crowd noise...
  610.                 ball_out_of_play=25;
  611.                 match_mode=bounds_rules();
  612.             }
  613.         }
  614.     }
  615. }
  616.  
  617. /******************************************************************************
  618. *****************************************************************************/
  619.  
  620. void rebound_post()
  621. {
  622. // Ball strikes post and rebounds off maintaining zdis...
  623.     shot_passed();            // For crowd noise...
  624.  
  625.     float x,y,d,ang;
  626.  
  627.     d=calc_dist(ballxdis,ballydis);
  628.     x=ballxdis/d;
  629.     y=ballydis/d;
  630.  
  631. // Get angle to come off ( favours 180 degrees )...
  632.  
  633.     ang=(float)(seed);
  634.     af_randomize();
  635.     ang+=(float)seed;
  636.     af_randomize();            // Favour 128...
  637.  
  638.     ang=ang*PI/128;
  639.  
  640.     ballxdis=((x*cos(ang))-(y*sin(ang)))*d*REBOUND_FACTOR;
  641.     ballydis=((y*cos(ang))+(x*sin(ang)))*d*REBOUND_FACTOR;
  642.  
  643.     rebound_ball=TRUE;
  644.  
  645.     if (shot_pending)
  646.         PlayCommentaryMessage(PM_POST);
  647.     
  648. }
  649.  
  650. /******************************************************************************
  651. *****************************************************************************/
  652.  
  653. void rebound_bar()
  654. {
  655. // Ball strikes cross-bar and rebounds off maintaining x,ydis...
  656.     shot_passed();            // For crowd noise...
  657.  
  658.     float z,d,ndxy,dxy,ang;
  659.  
  660.     dxy=calc_dist(ballxdis,ballydis);
  661.     d=calc_dist(dxy,ballzdis);
  662.     z=ballzdis/d;
  663.  
  664. // Get angle to come off ( favours 180 degrees )...
  665.  
  666.     ang=(float)(seed);
  667.     af_randomize();
  668.     ang+=(float)seed;
  669.     af_randomize();            // Favour 128...
  670.  
  671.     ang=ang*PI/128;
  672.  
  673.     ballzdis=((z*cos(ang))-(dxy/d*sin(ang)))*d*REBOUND_FACTOR;
  674.     ndxy=ABS(((dxy/d*cos(ang))+(z*sin(ang)))*d*REBOUND_FACTOR);
  675.  
  676.     ballxdis=-ballxdis*(ndxy/dxy);
  677.     ballydis=ballydis*(ndxy/dxy);
  678.  
  679.     rebound_ball=TRUE;
  680.  
  681.     if (shot_pending)
  682.         PlayCommentaryMessage(PM_CROSSBAR);
  683. }
  684.  
  685. /******************************************************************************
  686. *****************************************************************************/
  687.  
  688. void own_goal()
  689. {
  690.     goal_scorer=last_touch;
  691.  
  692.     inc_ogs(goal_scorer);
  693.  
  694.     if (penalty_game)
  695.         just_scored=PEN_SCORE_WAIT;
  696.     else
  697.         just_scored=SCORE_WAIT;
  698.  
  699.     reset_shot();
  700.     holder_lose_ball();
  701.     ball_out_of_play=25;    
  702.     do_goal_anim(0);
  703.     shamed_player=goal_scorer;
  704. }
  705.  
  706. /******************************************************************************
  707. *****************************************************************************/
  708.  
  709. void good_goal()
  710. {
  711.     inc_goal(goal_scorer);
  712.  
  713.     if (penalty_game)
  714.         just_scored=PEN_SCORE_WAIT;
  715.     else
  716.         just_scored=SCORE_WAIT;
  717.  
  718.     reset_shot();
  719.     holder_lose_ball();
  720.     ball_out_of_play=25;
  721.     do_goal_anim(0);
  722.     shamed_player=0;
  723. }
  724.  
  725. /******************************************************************************
  726. *****************************************************************************/
  727.  
  728. void hit_goal_post()
  729. {
  730.     rebound_post();
  731.     if (ballx>cntspot_x)
  732.         ballx=pitch_len-1;
  733.     else
  734.         ballx=1;
  735.     reset_shot();
  736. }
  737.  
  738. /******************************************************************************
  739. *****************************************************************************/
  740.  
  741. void hit_cross_bar()
  742. {
  743.     rebound_bar();
  744.     if (ballx>cntspot_x)
  745.         ballx=pitch_len-1;
  746.     else
  747.         ballx=1;
  748.     reset_shot();
  749. }
  750.  
  751. /******************************************************************************
  752. *****************************************************************************/
  753.  
  754. void hit_high_side_net()
  755. {
  756.     if (swerve!=0)
  757.         stop_ball_spin();
  758.     ballzdis=ballzdis/2;
  759.     ballxdis=ballxdis/2;
  760.     ballydis=-ballydis/2;
  761.     bally=top_post_y;
  762. }
  763.  
  764. /******************************************************************************
  765. *****************************************************************************/
  766.  
  767. void hit_low_side_net()
  768. {
  769.     if (swerve!=0)
  770.         stop_ball_spin();
  771.     ballzdis=ballzdis/2;
  772.     ballxdis=ballxdis/2;
  773.     ballydis=-ballydis/2;
  774.     bally=bot_post_y;
  775. }
  776.  
  777. /******************************************************************************
  778. *****************************************************************************/
  779.  
  780. void hit_top_net()
  781. {
  782.     if (swerve!=0)
  783.         stop_ball_spin();
  784.     ballz=goal_height+1;
  785.     ballzdis=0;
  786.  
  787.     if (ballxdis<0)
  788.         ballxdis-=2;
  789.     else
  790.         ballxdis+=2;
  791.  
  792.     ballxdis=ballxdis/2;
  793.     ballydis=ballydis/2;
  794. }
  795.  
  796. /******************************************************************************
  797. *****************************************************************************/
  798.  
  799. void hit_inside_back_net()
  800. {
  801.     if (swerve!=0)
  802.         stop_ball_spin();
  803.     ballzdis=ballzdis/2;
  804.     ballxdis=-ballxdis/2;
  805.     ballydis=ballydis/2;
  806.     ballx=1-goal_depth;
  807. }
  808.  
  809. /******************************************************************************
  810. *****************************************************************************/
  811.  
  812. void hit_inside_back_net_r()
  813. {
  814.     if (swerve!=0)
  815.         stop_ball_spin();
  816.     ballzdis=ballzdis/2;
  817.     ballxdis=-ballxdis/2;
  818.     ballydis=ballydis/2;
  819.     ballx=pitch_len+goal_depth-1;
  820. }
  821.  
  822. /******************************************************************************
  823. *****************************************************************************/
  824.  
  825. void hit_inside_top_net()
  826. {
  827.     if (swerve!=0)
  828.         stop_ball_spin();
  829.     ballz=goal_height-1;
  830.     ballzdis=0;
  831.  
  832.     ballxdis=ballxdis/2;
  833.     ballydis=ballydis/2;
  834. }
  835.  
  836. /******************************************************************************
  837. *****************************************************************************/
  838.  
  839. void hit_inside_high_side()
  840. {
  841.     if (swerve!=0)
  842.         stop_ball_spin();
  843.     ballzdis=ballzdis/2;
  844.     ballxdis=ballxdis/2;
  845.     ballydis=-ballydis/2;
  846.     bally=top_post_y+1;
  847. }
  848.  
  849. /******************************************************************************
  850. *****************************************************************************/
  851.  
  852. void hit_inside_low_side()
  853. {
  854.     if (swerve!=0)
  855.         stop_ball_spin();
  856.     ballzdis=ballzdis/2;
  857.     ballxdis=ballxdis/2;
  858.     ballydis=-ballydis/2;
  859.     bally=bot_post_y-1;
  860. }
  861.  
  862. /******************************************************************************
  863. *****************************************************************************/
  864.  
  865. short real_player(short p)
  866. {
  867.     if (match_half&1)
  868.     {
  869. // swapped...
  870.         p=((p>11) ? p-11:p+11);
  871.     }
  872.     return(p);
  873. }
  874.  
  875. /******************************************************************************
  876. *****************************************************************************/
  877.  
  878. short standard_player(short p)
  879. {
  880.     if (p>11)
  881.         p-=11;
  882.     return(p);
  883. }
  884.  
  885. /******************************************************************************
  886. *****************************************************************************/
  887.  
  888. short country(char t)
  889. {
  890.     short p;
  891.     if (t)
  892.         p=setup.team_b;
  893.     else
  894.         p=setup.team_a;
  895.  
  896.     return(p);
  897. }
  898.  
  899. /******************************************************************************
  900. *****************************************************************************/
  901.  
  902. void go_right_goal()
  903. {
  904.     if (golden_goal && (match_half>1 && match_half<4))
  905.     {
  906. // Sudden death... Golden goal has been scored! (End of match)
  907.         golden_goal=2;
  908.     }
  909.  
  910.     if (!ball_out_of_play)
  911.     {
  912.         ball_in_goal=TRUE;
  913.         last_goal=1;
  914.  
  915.         if (match_mode==NORMAL_PLAY)
  916.         {
  917.             if (match_half&1)
  918.                 team_b_goals++;
  919.             else
  920.                 team_a_goals++;
  921.  
  922.             if (penalty_game)
  923.                 EUROmatch_info.Team_B_penalties++;
  924.  
  925.             if (last_touch>11)
  926. // Deflection, own goal or keeper's poss...
  927.             {
  928.                 if (last_touch==KP_B)
  929.                 {
  930. // Keeper bad save...
  931.                     PlayCommentaryMessage(GL_KEEPER);
  932.                     goal_scorer=pre_kp_touch;
  933.                     if (goal_scorer<12)
  934.                     {
  935. // Opposition scored...
  936.                         do_goal_menu(team_a,standard_player(goal_scorer)-1,match_time.min);
  937.                         if (!penalty_game)
  938.                             GOAL_SCORED(0,(int)real_player(goal_scorer)-1,(int)match_time.min+(penalty_shot ? 256:0));
  939.                         good_goal();
  940.                     }
  941.                     else
  942.                     {
  943. // Own goal...
  944.                         do_owngoal_menu(team_b,standard_player(goal_scorer)-1,match_time.min);
  945.                         if (!penalty_game)
  946.                             GOAL_SCORED(0,(int)real_player(goal_scorer)-1,(int)match_time.min+512+(penalty_shot ? 256:0));
  947.                         own_goal();
  948.                     }
  949.                 }
  950.                 else
  951.                 {
  952.                     PlayCommentaryMessage(GL_DEFLECT);
  953.                     do_owngoal_menu(team_b,standard_player(last_touch)-1,match_time.min);
  954.                     if (!penalty_game)
  955.                         GOAL_SCORED(0,real_player(last_touch)-1,match_time.min+512+(penalty_shot ? 256:0));
  956.                     own_goal();
  957.                 }
  958.             }
  959.             else
  960.             {
  961.                 if (headed_ball)
  962.                     PlayCommentaryMessage(GL_HEADER);
  963.                 else
  964.                     if (rebound_ball)
  965.                         PlayCommentaryMessage(GL_POST);
  966.                     else
  967.                         if (max_sw_factor>GOOD_SWERVE)
  968.                             if (wall_is_up)
  969.                                 PlayCommentaryMessage(GL_CURVEWALL);
  970.                             else
  971.                                 PlayCommentaryMessage(GL_CURVE);
  972.                         else
  973.                             if (shot_speed>18)
  974.                                 PlayCommentaryMessage(GL_HARDKICK);
  975.                             else
  976.                                 PlayCommentaryMessage(GL_GENERIC);
  977.  
  978.                 do_goal_menu(team_a,standard_player(last_touch)-1,match_time.min);
  979.                 if (!penalty_game)
  980.                     GOAL_SCORED(0,real_player(last_touch)-1,match_time.min+(penalty_shot ? 256:0));
  981.  
  982.                 goal_scorer=last_touch;
  983.                 good_goal();
  984.             }
  985.         }
  986.     PauseCommentary();
  987.     }
  988. }
  989.  
  990. /******************************************************************************
  991. *****************************************************************************/
  992.  
  993. void go_left_goal()
  994. {
  995.     if (golden_goal && (match_half>1 && match_half<4))
  996.     {
  997. // Sudden death... Golden goal has been scored! (End of match)
  998.         golden_goal=2;
  999.     }
  1000.  
  1001.     if (!ball_out_of_play)
  1002.     {
  1003.         ball_in_goal=TRUE;
  1004.         last_goal=2;
  1005.  
  1006.         if (match_mode==NORMAL_PLAY)
  1007.         {
  1008.             if (match_half&1)
  1009.                 team_a_goals++;
  1010.             else
  1011.                 team_b_goals++;
  1012.  
  1013.             if (penalty_game)
  1014.                 EUROmatch_info.Team_A_penalties++;
  1015.  
  1016.             if (last_touch<12)
  1017. // Deflection, own goal or keeper's poss...
  1018.             {
  1019.                 if (last_touch==KP_A)
  1020.                 {
  1021. // Keeper bad save...
  1022.                     PlayCommentaryMessage(GL_KEEPER);
  1023.                     goal_scorer=pre_kp_touch;
  1024.                     if (goal_scorer>11)
  1025.                     {
  1026. // Opposition scored...
  1027.                         do_goal_menu(team_b,standard_player(goal_scorer)-1,match_time.min);
  1028.                         if (!penalty_game)
  1029.                             GOAL_SCORED(0,(int)real_player(goal_scorer)-1,(int)match_time.min+(penalty_shot ? 256:0));
  1030.                         good_goal();
  1031.                     }
  1032.                     else
  1033.                     {
  1034. // Own goal...
  1035.                         do_owngoal_menu(team_a,standard_player(goal_scorer)-1,match_time.min);
  1036.                         if (!penalty_game)
  1037.                             GOAL_SCORED(0,(int)real_player(goal_scorer)-1,(int)match_time.min+512+(penalty_shot ? 256:0));
  1038.                         own_goal();
  1039.                     }
  1040.                 }
  1041.                 else
  1042.                 {
  1043.                     PlayCommentaryMessage(GL_DEFLECT);
  1044.                     do_owngoal_menu(team_a,standard_player(last_touch)-1,match_time.min);
  1045.                     if (!penalty_game)
  1046.                         GOAL_SCORED(0,real_player(last_touch)-1,match_time.min+512+(penalty_shot ? 256:0));
  1047.                     own_goal();
  1048.                 }
  1049.             }
  1050.             else
  1051.             {
  1052.                 if (headed_ball)
  1053.                     PlayCommentaryMessage(GL_HEADER);
  1054.                 else
  1055.                     if (rebound_ball)
  1056.                         PlayCommentaryMessage(GL_POST);
  1057.                     else
  1058.                         if (max_sw_factor>GOOD_SWERVE)
  1059.                             PlayCommentaryMessage(GL_CURVE);
  1060.                         else
  1061.                             if (shot_speed>16)
  1062.                                 PlayCommentaryMessage(GL_HARDKICK);
  1063.                             else
  1064.                                 PlayCommentaryMessage(GL_GENERIC);
  1065.  
  1066.                 do_goal_menu(team_b,standard_player(last_touch)-1,match_time.min);
  1067.                 if (!penalty_game)
  1068.                     GOAL_SCORED(0,real_player(last_touch)-1,match_time.min+(penalty_shot ? 256:0));
  1069.  
  1070.                 goal_scorer=last_touch;
  1071.                 good_goal();
  1072.             }
  1073.         }
  1074.     PauseCommentary();
  1075.     }
  1076. }
  1077.  
  1078. /******************************************************************************
  1079. *****************************************************************************/
  1080.  
  1081. void outside_of_net(float f,float y,float z)
  1082. {
  1083.     float dx=ballx-prev_ballx;
  1084.     float dy=bally-prev_bally;
  1085.     float dz=ballz-prev_ballz;
  1086.     float x;
  1087.  
  1088.     if ((ballx<0 && prev_ballx>=0) || (ballx>pitch_len && prev_ballx<=pitch_len))
  1089.     {
  1090.         if ((z>=goal_height) && (z<goal_height+post_width)
  1091.             && (y>top_post_y-post_width) && (y<bot_post_y+post_width))
  1092. // Hit cross Bar...
  1093.         {
  1094.             hit_cross_bar();
  1095.         }
  1096.         else
  1097.         {
  1098.             if ((z<goal_height) && (y>top_post_y-post_width)
  1099.                 && (y<=top_post_y))
  1100. // Hit Top post...
  1101.             {
  1102.                 hit_goal_post();
  1103.             }
  1104.             else
  1105.             {
  1106.                 if ((z<goal_height) && (y<bot_post_y+post_width)
  1107.                     && (y>=bot_post_y))
  1108. // Hit Bot post...
  1109.                 {
  1110.                     hit_goal_post();
  1111.                 }
  1112.                 else
  1113.                 {
  1114. // Try top-side netting...
  1115.                     f=(top_post_y-prev_bally)/dy;
  1116.                     z=prev_ballz+(f*dz);
  1117.                     x=prev_ballx+(f*dx);
  1118.  
  1119.                     if (((x>-goal_depth && x<0)
  1120.                         || (x<pitch_len+goal_depth && x>pitch_len))
  1121.                          && (z<goal_height))
  1122. // Hit high side netting...
  1123.                     {
  1124.                         hit_high_side_net();
  1125.                     }
  1126.                     else
  1127. // Try low-side netting...
  1128.                     {
  1129.                         f=(bot_post_y-prev_bally)/dy;
  1130.                         z=prev_ballz+(f*dz);
  1131.                         x=prev_ballx+(f*dx);
  1132.  
  1133.                         if (((x>-goal_depth && x<0)
  1134.                             || (x<pitch_len+goal_depth && x>pitch_len))
  1135.                             && (z<goal_height))
  1136. // Hit low side netting...
  1137.                         {
  1138.                              hit_low_side_net();
  1139.                         }
  1140.                     }
  1141.                  }
  1142.             }
  1143.         }
  1144.     }
  1145.     else
  1146.     {
  1147.         if ((ballz<goal_height) && (prev_ballz>=goal_height))
  1148. // Falling... check top net...
  1149.         {
  1150.             f=(goal_height-prev_ballz)/dz;
  1151.             y=prev_bally+(f*dy);
  1152.             x=prev_ballx+(f*dx);
  1153.  
  1154.             if (((x>-goal_depth && x<0)
  1155.                 || (x<pitch_len+goal_depth && x>pitch_len))
  1156.                 && (y>top_post_y) && (y<bot_post_y))
  1157. // On top of net...
  1158.             {
  1159.                 hit_top_net();
  1160.             }
  1161.             else
  1162. // Try top-side netting...
  1163.             {
  1164.                 f=(top_post_y-prev_bally)/dy;
  1165.                 z=prev_ballz+(f*dz);
  1166.                 x=prev_ballx+(f*dx);
  1167.  
  1168.                 if (((x>-goal_depth && x<0)
  1169.                     || (x<pitch_len+goal_depth && x>pitch_len))
  1170.                      && (z<goal_height))
  1171. // Hit high side netting...
  1172.                 {
  1173.                     hit_high_side_net();
  1174.                 }
  1175.                 else
  1176. // Try low-side netting...
  1177.                 {
  1178.                     f=(bot_post_y-prev_bally)/dy;
  1179.                     z=prev_ballz+(f*dz);
  1180.                     x=prev_ballx+(f*dx);
  1181.  
  1182.                     if (((x>-goal_depth && x<0)
  1183.                         || (x<pitch_len+goal_depth && x>pitch_len))
  1184.                         && (z<goal_height))
  1185. // Hit low side netting...
  1186.                     {
  1187.                          hit_low_side_net();
  1188.                     }
  1189.                 }
  1190.             }
  1191.         }
  1192.     }
  1193. }
  1194.  
  1195. /******************************************************************************
  1196. *****************************************************************************/
  1197.  
  1198. void is_it_a_goal()
  1199. {
  1200.     float dx=ballx-prev_ballx;
  1201.     float dy=bally-prev_bally;
  1202.     float dz=ballz-prev_ballz;
  1203.     float f,x,y,z;
  1204.  
  1205.     if (!ball_in_goal)
  1206. // Not inside goal-net...
  1207.     {
  1208.         if (ballx<0)
  1209. // Crossed Left goal-line...
  1210.         {
  1211.             f=prev_ballx/dx;
  1212.             y=prev_bally-(f*dy);
  1213.             z=prev_ballz-(f*dz);
  1214.  
  1215.             if (prev_ballx>=0)
  1216.             {
  1217. // Just crossed goal-line...
  1218.  
  1219.                 if ((z<goal_height) && (y>top_post_y) && (y<bot_post_y))
  1220. // Its a goal!!!!
  1221.                 {
  1222.                     go_left_goal();
  1223.                 }
  1224.                 else
  1225.                 {
  1226.                     outside_of_net(f,y,z);
  1227.                 }
  1228.             }
  1229.             else
  1230.             {
  1231.                  outside_of_net(f,y,z);
  1232.             }
  1233.         }
  1234.         else
  1235. // Behind Left goal-line...
  1236.         {
  1237.             if (ballx>pitch_len)
  1238.             {
  1239.                 f=(pitch_len-prev_ballx)/dx;
  1240.                 y=prev_bally+(f*dy);
  1241.                 z=prev_ballz+(f*dz);
  1242.  
  1243.                 if (prev_ballx<pitch_len)
  1244.                 {
  1245.                     if ((z<goal_height) && (y>top_post_y) && (y<bot_post_y))
  1246. // Its a goal!!!!
  1247.                     {
  1248.                         go_right_goal();
  1249.                     }
  1250.                     else
  1251.                     {
  1252.                         outside_of_net(f,y,z);
  1253.                     }
  1254.                 }
  1255.                 else
  1256.                 {
  1257.                      outside_of_net(f,y,z);
  1258.                 }
  1259.             }
  1260.         }
  1261.     }
  1262.     else
  1263. // Inside goal-net...
  1264.     {
  1265.         if (ballx<0)
  1266. // Inside left goal...
  1267.         {
  1268.             if (ballx<-goal_depth)
  1269.                 hit_inside_back_net();
  1270.             if (bally<top_post_y)
  1271.                 hit_inside_high_side();
  1272.             if (bally>bot_post_y)
  1273.                 hit_inside_low_side();
  1274.             if (ballz>goal_height)
  1275.                 hit_inside_top_net();
  1276.         }
  1277.         else
  1278. // Inside right goal...
  1279.         {
  1280.             if (ballx>pitch_len+goal_depth)
  1281.                 hit_inside_back_net_r();
  1282.             if (bally<top_post_y)
  1283.                 hit_inside_high_side();
  1284.             if (bally>bot_post_y)
  1285.                 hit_inside_low_side();
  1286.             if (ballz>goal_height)
  1287.                 hit_inside_top_net();
  1288.         }
  1289.     }
  1290. }
  1291.  
  1292.  
  1293. /******************************************************************************
  1294. *****************************************************************************/
  1295.  
  1296. void ball_collision()
  1297. {        
  1298.     is_it_a_goal();
  1299.         
  1300.     prev_ballx=ballx;
  1301.     prev_bally=bally;
  1302.     prev_ballz=ballz;
  1303. }
  1304.  
  1305. /******************************************************************************
  1306. *****************************************************************************/
  1307.  
  1308. void oball_collision()
  1309. {
  1310.     if (ballx<cntspot_x)
  1311.     {
  1312.  
  1313. // Left side
  1314.         if (!ball_in_goal)
  1315.         {
  1316.  
  1317. // Not in goal
  1318.             if (ballx<0)
  1319.             {
  1320. // Behind posts
  1321.                 if (prev_ballx>=-goal_depth)
  1322.                 {
  1323.                     if ((prev_ballz<goal_height) || (ballz<goal_height))
  1324.                     {
  1325.                         if (bally<cntspot_y)
  1326.                         {
  1327. // High side
  1328.                             if ((bally>top_post_y) || (prev_bally>top_post_y))
  1329.                                 {
  1330.                                 if ((ballz-ballzdis)>=goal_height)
  1331.                                     hit_top_net();
  1332.                                 if ((bally-ballydis)<=top_post_y)
  1333.                                 {
  1334.                                     if ((ballx-ballxdis>post_width)
  1335.                                         && (ABS(ballxdis)>ABS(ballydis)))
  1336.                                         hit_goal_post();
  1337.                                     else
  1338.                                         hit_high_side_net();
  1339.                                 }
  1340.                                 else
  1341.                                     go_left_goal();
  1342.                                 }
  1343.                         }
  1344.                         else
  1345.                         {
  1346. // Low side
  1347.                             if (bally<bot_post_y)
  1348.                                 {
  1349.                                 if ((ballz-ballzdis)>=goal_height)
  1350.                                     hit_top_net();
  1351.                                 if ((bally-ballydis)>=cntspot_y+(4*prat))
  1352.                                 {
  1353.                                     if ((ballx-ballxdis>post_width)
  1354.                                         && (ABS(ballxdis)>ABS(ballydis)))
  1355.                                         hit_goal_post();
  1356.                                     else
  1357.                                         hit_low_side_net();
  1358.                                 }
  1359.                                 else
  1360.                                     go_left_goal();
  1361.                                 }
  1362.                         }
  1363.                     }
  1364.                 }
  1365.             }
  1366.             else
  1367.             {
  1368.                 if (ballx<=post_width)
  1369. // On goal line
  1370.                 {
  1371.                     if ((bally>top_post_y-post_width)
  1372.                         && (bally<=top_post_y)
  1373.                         && (ballz<=goal_height))
  1374.                         hit_goal_post();
  1375.                         
  1376.                     if ((bally<bot_post_y+post_width)
  1377.                         && (bally>=bot_post_y)
  1378.                         && (ballz<=goal_height))
  1379.                         hit_goal_post();
  1380.  
  1381.                     if ((bally>top_post_y-post_width)
  1382.                         && (bally<bot_post_y+post_width)
  1383.                         && (ballz>=goal_height)
  1384.                         && (ballz<goal_height+post_width))
  1385.                         hit_cross_bar();
  1386.                 }    
  1387.             }
  1388.         }
  1389.         else
  1390.         {
  1391. // Inside Left goal
  1392.             if (ballx<-goal_depth)
  1393.                 hit_inside_back_net();
  1394.             if (bally<top_post_y)
  1395.                 hit_inside_high_side();
  1396.             if (bally>bot_post_y)
  1397.                 hit_inside_low_side();
  1398.             if (ballz>goal_height)
  1399.                 hit_inside_top_net();
  1400.         }
  1401.     }
  1402.     else
  1403.     {
  1404. // Right side
  1405.         if (!ball_in_goal)
  1406.         {
  1407.  
  1408. // Not in goal
  1409.             if (ballx>pitch_len)
  1410.             {
  1411. // Behind posts
  1412.                 if (ballx<=pitch_len+goal_depth)
  1413.                 {
  1414.                     if (ballz<goal_height)
  1415.                     {
  1416.                         if (bally<cntspot_y)
  1417.                         {
  1418. // High side
  1419.                             if (bally>top_post_y)
  1420.                                 {
  1421.                                 if ((ballz-ballzdis)>=goal_height)
  1422.                                     hit_top_net();
  1423.                                 if ((bally-ballydis)<=top_post_y)
  1424.                                 {
  1425.                                     if ((ballx-ballxdis<pitch_len-post_width)
  1426.                                         && (ABS(ballxdis)>ABS(ballydis)))
  1427.                                         hit_goal_post();
  1428.                                     else
  1429.                                         hit_high_side_net();
  1430.                                 }
  1431.                                 else
  1432.                                     go_right_goal();
  1433.                                 }
  1434.                         }
  1435.                         else
  1436.                         {
  1437. // Low side
  1438.                             if (bally<bot_post_y)
  1439.                                 {
  1440.                                 if ((ballz-ballzdis)>=goal_height)
  1441.                                     hit_top_net();
  1442.                                 if ((bally-ballydis)>=cntspot_y+(4*prat))
  1443.                                 {
  1444.                                     if ((ballx-ballxdis<pitch_len-post_width)
  1445.                                         && (ABS(ballxdis)>ABS(ballydis)))
  1446.                                         hit_goal_post();
  1447.                                     else
  1448.                                         hit_low_side_net();
  1449.                                 }
  1450.                                 else
  1451.                                     go_right_goal();
  1452.                                 }
  1453.                         }
  1454.                     }
  1455.                 }
  1456.             }
  1457.             else
  1458.             {
  1459.                 if (ballx>=pitch_len-post_width)
  1460. // On goal line
  1461.                 {
  1462.                     if ((bally>top_post_y-post_width)
  1463.                         && (bally<=top_post_y)
  1464.                         && (ballz<=goal_height))
  1465.                         hit_goal_post();
  1466.                         
  1467.                     if ((bally<bot_post_y+post_width)
  1468.                         && (bally>=bot_post_y)
  1469.                         && (ballz<=goal_height))
  1470.                         hit_goal_post();
  1471.  
  1472.                     if ((bally>top_post_y-post_width)
  1473.                         && (bally<bot_post_y+post_width)
  1474.                         && (ballz>=goal_height)
  1475.                         && (ballz<goal_height+post_width))
  1476.                         hit_cross_bar();
  1477.                 }    
  1478.             }
  1479.         }
  1480.         else
  1481.         {
  1482. // Inside Right goal
  1483.             if (ballx>pitch_len+goal_depth)
  1484.                 hit_inside_back_net_r();
  1485.             if (bally<top_post_y)
  1486.                 hit_inside_high_side();
  1487.             if (bally>bot_post_y)
  1488.                 hit_inside_low_side();
  1489.             if (ballz>goal_height)
  1490.                 hit_inside_top_net();
  1491.         }
  1492.     }
  1493. }
  1494.  
  1495. /******************************************************************************
  1496. *****************************************************************************/
  1497.  
  1498. void get_ball_speed()
  1499. {
  1500.     float tot=ABS(ballxdis)+ABS(ballydis)+ABS(ballzdis);
  1501.     ball_speed=sqrt(tot);
  1502. }
  1503.  
  1504. /******************************************************************************
  1505. *****************************************************************************/
  1506.  
  1507. void ball_limbo(int p,float c)
  1508. {
  1509.     ball_limbo_c=ABS(c);
  1510.     ball_limbo_p=p;
  1511.     ball_limbo_on=TRUE;
  1512. }
  1513.  
  1514. /******************************************************************************
  1515. *****************************************************************************/
  1516.  
  1517. void ball_possession()
  1518. {
  1519.  
  1520. // Calculate possession for audio...
  1521.     if (!just_scored && !match_mode && last_touch!=KP_A && last_touch!=KP_B)
  1522.     {
  1523.         good_poss+=(last_touch<12 ? ballx/20:-(pitch_len-ballx)/20);
  1524.     }
  1525.  
  1526.     if (ABS(good_poss)>MAX_GOOD_POSS)
  1527.     {
  1528.         if (audio_version)
  1529.             PlayPossessionSample((good_poss<0 ? team_b:team_a));
  1530.  
  1531.         good_poss=0;
  1532.     }
  1533. }
  1534.  
  1535. /******************************************************************************
  1536. *****************************************************************************/
  1537.  
  1538. void process_ball()
  1539. {
  1540.     ball_possession();
  1541.  
  1542.     if (ball_limbo_on>0)
  1543.     {
  1544.  
  1545. // Ball is bound to a player's animation and should not be processed
  1546. // until the contact point of animation is exceeded...
  1547.  
  1548.         if (teams[ball_limbo_p-1].tm_frm+teams[ball_limbo_p-1].tm_fstep>ball_limbo_c)
  1549. // Contact exceeded...
  1550.         {
  1551.             ball_limbo_on=FALSE;
  1552.             if (teams[ball_limbo_p-1].tm_anim==MC_KICKOUT)
  1553.                 play_fx(PS_HARDKICK,ballx,bally);
  1554.         }                
  1555.     }
  1556.  
  1557.     if ((!ball_limbo_on) && (!ball_poss || (ball_poss && teams[ball_poss-1].contact<0)))
  1558.     {
  1559.         prediction=FALSE;
  1560.  
  1561.         if (shot_acknowledged)
  1562.             shot_acknowledged--;                // Counter for re-acknowledgement.
  1563.  
  1564. //    if ((shot_pending) && (shooter==last_touch))
  1565.         if (shot_pending)
  1566.         {
  1567.             if (!(++shot_pending))
  1568.                 shot_pending=1;
  1569.         }
  1570.         else
  1571.         {
  1572.             shot_pending=0;
  1573.             real_shot=0;
  1574.         }
  1575.  
  1576.         get_ball_speed();
  1577.         if (ball_out_of_play)
  1578.         {
  1579.             ball_trajectory();
  1580.             ball_collision();
  1581.             if (just_scored)
  1582.             {
  1583.                 if (!(--just_scored))
  1584.                 {
  1585.                     ResumeCommentary();
  1586.                     PlayScoreSample(team_a_goals,team_b_goals);
  1587.                 }
  1588.             }
  1589.             else
  1590.             {
  1591.                 if (!--ball_out_of_play && match_mode!=SWAP_ENDS)
  1592.                 {
  1593.                     respot_ball();
  1594.                     get_ball_zone();
  1595.                     predict_ball();
  1596.                 }
  1597.             }
  1598.             stadium_bounds();
  1599.         }
  1600.         else
  1601.         {
  1602.             ball_trajectory();
  1603.             ball_collision();
  1604.             if (!just_scored && match_mode!=SWAP_ENDS && match_half<=10)
  1605.             {
  1606.                 pitch_bounds();
  1607.                 get_ball_zone();
  1608.                 predict_ball();
  1609.             }
  1610.         }
  1611.     }
  1612. }
  1613.  
  1614.